package com.xiaolei.openokjoke.Adapters;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;


import androidx.recyclerview.widget.RecyclerView;

import com.xiaolei.openokjoke.R;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by zhuxuyang on 17/1/4.
 */

public abstract class RecyclerBaseAdapter<T> extends RecyclerView.Adapter {
    private static final int VIEW_TYPE_BASE = 100;
    private static final int VIEW_TYPE_EMPTY = 0;
    private static final int VIEW_TYPE_FOOT = 1;

    protected LayoutInflater mInflater;

    private boolean mHasEmpty = false;
    private boolean mLoadMore = false;

    private View mEmptyView;
    private int mDefaultEmptyViewID;
    private int mLoadMoreViewID;

    private OnItemClickListener mOnItemClickListener;
    private OnLoadMoreListener mLoadMoreListener;

    private List<T> mListData;

    private String emptyStr = "";
    private int emptyRes = 0;

    public RecyclerBaseAdapter(Context context) {
        mInflater = LayoutInflater.from(context);
        mDefaultEmptyViewID = R.layout.item_default_empty;
        mLoadMoreViewID = R.layout.item_load_more;
        mListData = new ArrayList<>();
    }

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        if (viewType == VIEW_TYPE_EMPTY) {
            if (mEmptyView != null) {
                return new DefaultViewHolder(mEmptyView);
            } else {
                return new DefaultViewHolder(mInflater.inflate(mDefaultEmptyViewID, parent, false));
            }
        } else if (viewType == VIEW_TYPE_FOOT) {
            return new DefaultViewHolder(mInflater.inflate(mLoadMoreViewID, parent, false));
        } else {
            return creatingViewHolder(parent, viewType - VIEW_TYPE_BASE);
        }
    }

    @Override
    public void onBindViewHolder(final RecyclerView.ViewHolder holder, int position) {
        if (holder instanceof DefaultViewHolder) {
            DefaultViewHolder vh = (DefaultViewHolder) holder;
            if (!"".equals(emptyStr)) {
                vh.tv_tip.setText(emptyStr);
            }
            if (emptyRes != 0) {
                vh.iv_empty.setImageResource(emptyRes);
            }
        }
        if (!(holder instanceof DefaultViewHolder)) {
            holder.itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    //int pos = holder.getAdapterPosition();
                    int pos = holder.getPosition();
                    if (mOnItemClickListener != null && pos != RecyclerView.NO_POSITION) {
                        mOnItemClickListener.onItemClick(holder);
                    }
                }
            });
            bindingViewHolder(holder, position);
        }
    }

    @Override
    public int getItemViewType(int position) {
        int realSize = getDataSize();
        if (mHasEmpty && realSize == 0) {
            return VIEW_TYPE_EMPTY;
        } else if (mLoadMore && position == realSize) {
            return VIEW_TYPE_FOOT;
        } else {
            return gettingItemViewType(position) + VIEW_TYPE_BASE;
        }
    }

    /**
     * 子类实现创建ViewHolder
     *
     * @param parent
     * @param viewType
     * @return
     */
    public abstract RecyclerView.ViewHolder creatingViewHolder(ViewGroup parent, int viewType);

    /**
     * 子类实现绑定ViewHolder
     *
     * @param holder
     * @param position
     */
    public abstract void bindingViewHolder(RecyclerView.ViewHolder holder, int position);

    /**
     * 子类实现获取ViewType
     *
     * @param position
     * @return
     */
    public int gettingItemViewType(int position) {
        return 0;
    }

    /**
     * 系统自动调用
     *
     * @return
     */
    @Override
    public int getItemCount() {
        int realSize = getDataSize();
        if (realSize == 0 && mHasEmpty) {
            // 是否是空布局
            return 1;
        } else {
            // 是否显示加载更多布局
            return realSize + (mLoadMore ? 1 : 0);
        }
    }

    /**
     * 返回列表数据的真实长度
     *
     * @return
     */
    public int getDataSize() {
        return mListData.size();
    }

    /**
     * 默认会使用ViewHolder
     */
    private static class DefaultViewHolder extends RecyclerView.ViewHolder {
        TextView tv_tip;
        ImageView iv_empty;

        public DefaultViewHolder(View itemView) {
            super(itemView);
            tv_tip = (TextView) itemView.findViewById(R.id.tv_tip);
            iv_empty = (ImageView) itemView.findViewById(R.id.iv_empty);
        }
    }

    public interface OnLoadMoreListener {
        void loadMore();
    }

    public void setOnLoadMoreListener(OnLoadMoreListener listener) {
        mLoadMoreListener = listener;
    }

    public OnLoadMoreListener getOnLoadMoreListener() {
        return mLoadMoreListener;
    }

    /**
     * item click回调方法
     */
    public interface OnItemClickListener {
        void onItemClick(RecyclerView.ViewHolder viewHolder);
    }

    /**
     * 是否需要显示空视图
     *
     * @param hasEmpty
     */
    public void setHasEmpty(boolean hasEmpty) {
        mHasEmpty = hasEmpty;
        if (getDataSize() == 0) {
            notifyDataSetChanged();
        }
    }

    /**
     * 设置是否需要上拉加载更多
     *
     * @param loadMore
     */
    public void setLoadMore(boolean loadMore) {
        boolean oldValue = mLoadMore;
        mLoadMore = loadMore;
        if (!oldValue && mLoadMore) {
            notifyItemInserted(getItemCount() - 1);
        } else if (oldValue && !mLoadMore) {
            notifyItemRemoved(getItemCount() - 1);
        }
    }

    public boolean hasLoadMore() {
        return mLoadMore;
    }

    public T getItem(int index) {
        return mListData.get(index);
    }

    public List<T> getData() {
        return mListData;
    }

    public void addAll(List<T> list) {
        mListData.addAll(list);
        if (mListData.size() == list.size()) {
            notifyDataSetChanged();
        } else {
            notifyItemRangeInserted(getItemCount() - list.size() - 1, list.size());
        }
    }


    public void add(T t) {
        mListData.add(t);
        if (mListData.size() == 1) {
            notifyDataSetChanged();
        } else {
            notifyItemInserted(getItemCount() - 1);
        }
    }

    public int indexOf(T t) {
        return mListData.indexOf(t);
    }

    public void insert(int index, T t) {
        if (index > mListData.size()) {
            throw new ArrayIndexOutOfBoundsException();
        } else {
            mListData.add(index, t);
        }

        if (mListData.size() == 1) {
            notifyDataSetChanged();
        } else {
            notifyItemInserted(index);
            notifyItemRangeChanged(index, mListData.size() - index);//通知数据与界面重新绑定
        }
    }

    public void insert(int index, List<T> list) {
        if (index > mListData.size()) {
            throw new ArrayIndexOutOfBoundsException();
        } else {
            mListData.addAll(index, list);
        }

        if (mListData.size() == list.size()) {
            notifyDataSetChanged();
        } else {
            notifyItemRangeInserted(index, list.size());
        }
    }

    public void remove(T t) {
        int index = indexOf(t);
        mListData.remove(index);
        notifyDataSetChanged();
    }

    public void remove(int index) {
        removeWithoutNotify(index);
        //notifyItemRemoved(index + 1);
        notifyDataSetChanged();
    }


    public void removeWithoutNotify(int index) {
        mListData.remove(index);
    }

    public void clear() {
        mListData.clear();
        setLoadMore(false);
        notifyDataSetChanged();
    }

    public void updateData(List<T> list) {
        if (mListData.size() != list.size()) {
            mListData.clear();
            mListData.addAll(list);
            notifyDataSetChanged();
        } else {
            mListData = list;
            notifyDataSetChanged();
        }
    }

    /**
     * 设置监听方法
     *
     * @param listener OnItemClickListener
     */
    public void setOnItemClickListener(OnItemClickListener listener) {
        this.mOnItemClickListener = listener;
    }

    protected void setEmptyView(View view) {
        mEmptyView = view;
    }

    public void setEmptyDesc(String desc) {
        emptyStr = desc;
    }

    public void setEmptyRes(int res) {
        emptyRes = res;
    }
}
